/**
 * 
 */
package commons.base.netty.http;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;

/**
 * 默认HTTP处理器
 * 实现了业务逻辑线程池，URI路由和请求解析
 * @author yuan<cihang.yuan@happyelements.com>
 * @since 1.7
 */
@Sharable
public class DefaultHttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

	private static final Logger log = LogManager.getLogger(DefaultHttpHandler.class);
	
	/** URI路由器 */
	private HttpRouter httpRouter;
	/** 业务线程池 */
	private ExecutorService executorService;
	private ChannelInvalidPolicy channelInvalidPolicy;
	
	public DefaultHttpHandler(HttpRouter httpRouter, ExecutorService executorService, ChannelInvalidPolicy channelInvalidPolicy){
		this.httpRouter = httpRouter;
		this.executorService = executorService;
		this.channelInvalidPolicy = channelInvalidPolicy;
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		log.error("[DefaultHttpHandler][exceptionCaught]" + cause.getMessage(), cause);
	}
	
	@Override
	public void channelRead0(final ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
		// 请求对象计数器加一，需要在HttpTask里手动release
		
        try {
			executorService.submit(new HttpTask(httpRouter, ctx, req.retain(), channelInvalidPolicy));
		} catch (RejectedExecutionException e) {
			// 达到处理能力上限
			ctx.channel().close();
			req.release();
		}
	}
	
}
